/*
 * @(#)DBDumper.java	2008/07/25
 *
 * Copyright 2008 Web & Zen Multimedia, All rights reserved.
 * Use is subject to license terms.
 */

package it.wzm.lightweightlog;

import java.util.Properties;
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Date;

/**
 * Used for dumping entries in a given database table
 * @author Leonardo Celati
 */
class DBDumper extends Dumper {
    
    /**
     * As required by serialization
     */
    static final long serialVersionUID=20080725L;
    
    /**
     * Url database
     */
    private String url;
    /**
     * User access
     */
    private String usr;
    /**
     * Password access
     */
    private String pwd;
    /**
     * DB driver
     */
    private String driver;
    /**
     * Prepared statement string
     */
    private String pstmt;
    /**
     * Prepared statement itself
     */
    private PreparedStatement ps;
    /**
     * Connection
     */
    private Connection c;
    
    /**
     * Build a dumper from a given name and properties set
     * @param p Set of properties
     */
    public DBDumper(Properties p) {
        // calling super constructor
        super(p);
    }
    
    /**
     * Adding our custom property
     */
    @Override
    protected void postinit() {
        // trying to get db parameter...
        this.driver=String.valueOf(this.get("driver"));
        this.pwd=String.valueOf(this.get("pwd"));
        this.url=String.valueOf(this.get("url"));
        this.usr=String.valueOf(this.get("usr"));
        
        // if we don't find a prepared statement
        // we use the default one
        if (this.get("pstmt")!=null)
            this.pstmt=String.valueOf(this.get("pstmt"));
        else
            this.pstmt=DEFAULT_PREPARED_STMT;
        
        // we try to load the driver directly on the constructor
        // so we let the open and close method only dealing
        // with Connection and PreparedStatement....
        // The class not found exception throws a Runtime exception...
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            throw new ObjectInitializationException(e);
        }        
    }
    
    /*
     * Open the database connection
     * @see it.wzm.common.lightweightlog.client.Dumper#open()
     */
    @Override
    protected void open() throws DumperException {
        try {
            c = DriverManager.getConnection(url, usr, pwd);
            ps = c.prepareStatement(pstmt);
        } catch (SQLException e) {
            throw new DumperException(e.getMessage());
        }
    }
    
    @Override
    protected void close() throws DumperException {
        try {
            if (ps!=null) {
                ps.clearParameters();
                ps.close();
            }
            if (c!=null) {
                c.close();
            }
        } catch (SQLException e) {
            throw new DumperException("cannot close DBDumper " + e.getMessage());
        }
    }
        
    
    @Override
    protected void write(Entry e) throws DumperException {
        
        try {
            
            // just in case
            ps.clearParameters();
            // following the order we set parameter
            // timestamp, message, severity, classname, name
            
            //ps.setTimestamp(1, new java.sql.Timestamp(e.getTimestamp().getTime()));
            //ps.setDate(1, new Date(e.getTimestamp()));
            ps.setTimestamp(1, new java.sql.Timestamp(e.getTimestamp()));
            //ps.setTimestamp(1, new Date(e.getTimestamp()));
            ps.setString(2, e.getMessage());
            ps.setString(3, e.getSeverity().toString());
            ps.setString(4, e.getClassname());
            ps.setString(5, e.getName());
            
            // ready to execute
            ps.execute();
            //if (!ps.execute()) {
            //	throw new DumperException("Insert fail");
            //}            
        } catch (SQLException ex) {
            throw new DumperException(ex);
        }        
    }
    
}
